# encoding:utf-8

import json
import os
import pickle

# 将所有可用的配置项写在字典里,
available_setting = {
    "address": "",  # 服务器地址
    "channel": "",  # 渠道
    "KEY_1": "",  # key
    "call_1": "",  # 称呼
    "age_1": "",  # 年龄
    "city_1": "",  # 城市
    "store_1": "",  # 门店
    "KEY_2": "",
    "call_2": "",
    "age_2": "",
    "city_2": "",
    "store_2": "",
    "KEY_3": "",
    "call_3": "",
    "age_3": "",
    "city_3": "",
    "store_3": "",
    "KEY_4": "",
    "call_4": "",
    "age_4": "",
    "city_4": "",
    "store_4": "",
    "KEY_5": "",
    "call_5": "",
    "age_5": "",
    "city_5": "",
    "store_5": "",
    "keywords": "",  # 关键词,如有不回复则不进行回复
    "message_hour_1": "",  # 调用主动消息开始时间
    "message_hour_2": "",  # 调用主动消息结束时间
    "message_interval": "",  # 调用主动消息间隔
    "debug": False,  # 是否开启debug模式，开启后会打印更多日志
    "appdata_dir": "",
}


class Config(dict):
    def __init__(self, d=None):
        super().__init__()
        if d is None:
            d = {}
        for k, v in d.items():
            self[k] = v
        # user_datas: 用户数据，key为用户名，value为用户数据，也是dict
        self.user_datas = {}

    def __getitem__(self, key):
        if key not in available_setting:
            raise Exception("key {} not in available_setting".format(key))
        return super().__getitem__(key)

    def __setitem__(self, key, value):
        if key not in available_setting:
            raise Exception("key {} not in available_setting".format(key))
        return super().__setitem__(key, value)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError as e:
            return default
        except Exception as e:
            raise e

    # Make sure to return a dictionary to ensure atomic
    def get_user_data(self, user) -> dict:
        if self.user_datas.get(user) is None:
            self.user_datas[user] = {}
        return self.user_datas[user]

    def load_user_datas(self):
        try:
            with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb") as f:
                self.user_datas = pickle.load(f)
                # logger.info("[Config] User datas loaded.")
                # print(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb")
        # except FileNotFoundError as e:
        # logger.info("[Config] User datas file not found, ignore.")
        except Exception as e:
            # logger.info("[Config] User datas error: {}".format(e))
            self.user_datas = {}

    def save_user_datas(self):
        try:
            with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "wb") as f:
                pickle.dump(self.user_datas, f)
                # logger.info("[Config] User datas saved.")
        except Exception as e:
            pass
            # logger.info("[Config] User datas error: {}".format(e))


config = Config()


def initialize_config_if_missing():
    config_path = "./config.json"

    if not os.path.exists(config_path):
        # 如果文件不存在，创建并初始化
        with open(config_path, mode="w", encoding="utf-8") as f:
            default_config = {
                "address": "",
                "channel": "",
                "KEY_1": "",
                "call_1": "",
                "age_1": "",
                "city_1": "",
                "store_1": "",
                "KEY_2": "",
                "call_2": "",
                "age_2": "",
                "city_2": "",
                "store_2": "",
                "KEY_3": "",
                "call_3": "",
                "age_3": "",
                "city_3": "",
                "store_3": "",
                "KEY_4": "",
                "call_4": "",
                "age_4": "",
                "city_4": "",
                "store_4": "",
                "KEY_5": "",
                "call_5": "",
                "age_5": "",
                "city_5": "",
                "store_5": "",
                "keywords": "",
                "message_hour_1": "",
                "message_hour_2": "",
                "message_interval": "",
            }
            json.dump(default_config, f, indent=4, ensure_ascii=False)
            return False
    else:
        return True


def check_config(index):
    # 检查各个必配置的项是否为空
    config_path = "./config.json"
    try:
        with open(config_path, 'r') as file:
            config = json.load(file)
        if index == 1:
            required_keys = ["address", "channel", "KEY_1", "message_hour_1", "message_hour_2",
                             "message_interval"]  # 必填项
        elif index == 2:
            required_keys = ["address", "channel", "KEY_2", "message_hour_1", "message_hour_2", "message_interval"]
        elif index == 3:
            required_keys = ["address", "channel", "KEY_3", "message_hour_1", "message_hour_2", "message_interval"]
        elif index == 4:
            required_keys = ["address", "channel", "KEY_4", "message_hour_1", "message_hour_2", "message_interval"]
        elif index == 5:
            required_keys = ["address", "channel", "KEY_5", "message_hour_1", "message_hour_2", "message_interval"]

        for key in required_keys:
            if key not in config or config[key] is None or config[key] == "":
                return False, f"配置项 {key} 为空或未配置"

        return True, "所有必填项已正确配置"
    except FileNotFoundError:
        return False, "配置文件未找到"
    except json.JSONDecodeError:
        return False, "配置文件格式错误"


def load_config():
    global config
    config_path = "./config.json"

    config_str = read_file(config_path)
    # logger.debug("[INIT] config str: {}".format(config_str))

    # 将json字符串反序列化为dict类型
    config = Config(json.loads(config_str))

    # override config with environment variables.
    # Some online deployment platforms (e.g. Railway) deploy project from github directly. So you shouldn't put your secrets like api key in a config file, instead use environment variables to override the default config.
    for name, value in os.environ.items():
        name = name.lower()
        if name in available_setting:
            # logger.info("[INIT] override config by environ args: {}={}".format(name, value))
            try:
                config[name] = eval(value)
            except:
                if value == "false":
                    config[name] = False
                elif value == "true":
                    config[name] = True
                else:
                    config[name] = value

    # if config.get("debug", False):
    # logger.setLevel(logging.DEBUG)
    # logger.debug("[INIT] set log level to DEBUG")

    # logger.info("[INIT] load config: {}".format(config))

    config.load_user_datas()


def get_root():
    return os.path.dirname(os.path.abspath(__file__))


def read_file(path):
    with open(path, mode="r", encoding="utf-8") as f:
        return f.read()


def conf():
    return config


def get_appdata_dir():
    data_path = os.path.join(get_root(), conf().get("appdata_dir", ""))
    if not os.path.exists(data_path):
        # logger.info("[INIT] data path not exists, create it: {}".format(data_path))
        os.makedirs(data_path)
    return data_path


def subscribe_msg():
    trigger_prefix = conf().get("single_chat_prefix", [""])[0]
    msg = conf().get("subscribe_msg", "")
    return msg.format(trigger_prefix=trigger_prefix)


# global plugin config
plugin_config = {}


def write_plugin_config(pconf: dict):
    """
    写入插件全局配置
    :param pconf: 全量插件配置
    """
    global plugin_config
    for k in pconf:
        plugin_config[k.lower()] = pconf[k]


def pconf(plugin_name: str) -> dict:
    """
    根据插件名称获取配置
    :param plugin_name: 插件名称
    :return: 该插件的配置项
    """
    return plugin_config.get(plugin_name.lower())


# 全局配置，用于存放全局生效的状态
global_config = {
    "admin_users": []
}
